﻿// TelnetDevice.cpp : 定义 DLL 应用程序的导出函数。
//

#include "imgDrv.h"
#include <ossString.h>
#include <ossDir.h>
#include <ossTime.h>
#include "jpeglib.h"

BEGIN_OSS_MESSAGE_MAP(ImgDrv,LabelDeviceDriver)
	OSS_COMMAND("getShowImg",ImgDrv::OnGetShowImg)
	OSS_COMMAND("decodeImg", ImgDrv::OnDecodeImg)

    OSS_COMMAND("getImgHeaderInfo", ImgDrv::OnGetImgHeaderInfo)
    OSS_COMMAND("decodeImgMsg",ImgDrv::OnDecodeImg_In)
	//
END_OSS_MESSAGE_MAP()

ImgDrv::ImgDrv(LabelDeviceBase* pParent)
    :LabelDeviceDriver(pParent)
{    
}

ImgDrv::~ImgDrv()
{
    if (m_byRgbBuf)
    {
        delete[]m_byRgbBuf;
    }
}

/**
    *      初始化实例的方法
    */
BOOL ImgDrv::DeviceInit(OssJson& initJson)
{
    return LabelDeviceDriver::DeviceInit(initJson);
}


/**
    *      逆初始化方法
    */
BOOL ImgDrv::DeviceDeinit()
{
    return LabelDeviceDriver::DeviceDeinit();
}

/**
    *      启动实例
    */
BOOL ImgDrv::DeviceStart()
{
    return LabelDeviceDriver::DeviceStart();
}

/**
    *      逆初始化方法
    */
BOOL ImgDrv::DeviceStop()
{
    return LabelDeviceDriver::DeviceStop();
}


/**
	*		获取安装命令
	*/
int ImgDrv::OnGetShowImg(WPARAM wparam,LPARAM lparam)
{
    OssJson& request = *(OssJson*)wparam;
    OssJson& response = request;
    OssJson& msg = response["msg"];

    //clear
    msg = "";

    //
    msg["width"] = m_iWidth;
    msg["height"] = m_iHeight;
    msg["format"] = "rgb8";
    msg["data"] = m_byRgbBuf;

    response["to"] = response["from"];
    response["from"] = GetDeviceId();

    SendResponse(response);
	return MSG_OK;
}

/**
     *      解码图片
     */
int ImgDrv::OnDecodeImg(WPARAM wparam, LPARAM lparam)
{
    OssJson& request = *(OssJson*)wparam;
    OssJson& response = request;
    OssJson& msg = response["msg"];
	OssJson& src = msg["src"];

	if (src.ValueType() != JSON_STRING_VAL)
	{
		return MSG_PARAM_ERROR;
	}

    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    FILE* infile;

    if ((infile = fopen(src.asCString(), "rb")) == NULL) {
        WriteLog( "can't open %s\n", src.asCString());
        return -1;
    }


    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_decompress(&cinfo);

    jpeg_stdio_src(&cinfo, infile);

    jpeg_read_header(&cinfo, TRUE);

    //printf("image_width = %d\n", cinfo.image_width);
    //printf("image_height = %d\n", cinfo.image_height);
    //printf("num_components = %d\n", cinfo.num_components);
    //printf("enter scale M/N:\n");

    jpeg_start_decompress(&cinfo);

    ////输出的图象的信息
    //printf("output_width = %d\n", cinfo.output_width);
    //printf("output_height = %d\n", cinfo.output_height);
    //printf("output_components = %d\n", cinfo.output_components);

    int row_stride = cinfo.output_width * cinfo.output_components;
    /* Make a one-row-high sample array that will go away when done with image */

    int bufMax = row_stride * cinfo.image_height;
    if (m_iRgbBufMax < bufMax)
    {
        if (m_byRgbBuf )
        {
            delete[]m_byRgbBuf;
        }

        m_byRgbBuf = new BYTE[bufMax];
        if (m_byRgbBuf == nullptr)
        {
            m_iRgbBufMax = 0;
            fclose(infile);
            return MSG_MEMORY_ERROR;
        }

        m_iRgbBufMax = bufMax;
    }

    m_iWidth = cinfo.image_width;
    m_iHeight = cinfo.image_height;

    long counter = 0;

    JSAMPROW row_pointer[1];
    while (cinfo.output_scanline < cinfo.output_height) {
        row_pointer[0] = &m_byRgbBuf[(cinfo.output_height - cinfo.output_scanline - 1) * row_stride];
        jpeg_read_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_decompress(&cinfo);

    jpeg_destroy_decompress(&cinfo);

    fclose(infile);

    //clear
    msg = "";

    //
    msg["width"] = m_iWidth;
    msg["height"] = m_iHeight;
    msg["format"] = "RGB8";
    msg["data"] = m_byRgbBuf;

    response["to"] = response["from"];
    response["from"] = GetDeviceId();

    SendResponse(response);
	return MSG_OK;
}



/**
 *      获取图片头域数据，包括分辨率、格式
 */
int ImgDrv::OnGetImgHeaderInfo(WPARAM wparam, LPARAM lparam)
{
    OssJson& request = *(OssJson*)wparam;
    OssJson& response = request;
    OssJson& msg = response["msg"];
    OssJson& src = msg["src"];

    if (src.ValueType() != JSON_STRING_VAL)
    {
        return MSG_PARAM_ERROR;
    }

    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    FILE* infile;

    if ((infile = fopen(src.asCString(), "rb")) == NULL) {
        WriteLog("can't open %s\n", src.asCString());
        return MSG_EXECUTE_ERROR;
    }


    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_decompress(&cinfo);

    jpeg_stdio_src(&cinfo, infile);

    jpeg_read_header(&cinfo, TRUE);

    //jpeg_start_decompress(&cinfo);

    msg["width"] = (int)cinfo.image_width;
    msg["height"] = (int)cinfo.image_height;
    msg["format"] = "RGB8";
    msg["rowStride"] = (int)cinfo.image_width * cinfo.num_components;
    msg["bufMin"] = (int)(cinfo.image_width * cinfo.image_height *3);

    //jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);

    fclose(infile);

    return MSG_OK;
}

/**
     *      解码图片(内部消息方式)
     */
int ImgDrv::OnDecodeImg_In(WPARAM wparam, LPARAM lparam)
{
    OssJson& request = *(OssJson*)wparam;
    OssJson& response = request;
    OssJson& msg = response["msg"];
    OssJson& src = msg["src"];
    OssJson& rgbBuff = msg["rgbBuff"];
    OssJson& buffMax = msg["buffMax"];

    char* toUi = (char*)lparam;

    if (src.ValueType() != JSON_STRING_VAL)
    {
        return MSG_PARAM_ERROR;
    }

    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    FILE* infile;

    if ((infile = fopen(src.asCString(), "rb")) == NULL) {
        WriteLog("can't open %s\n", src.asCString());
        return MSG_EXECUTE_ERROR;
    }


    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_decompress(&cinfo);

    jpeg_stdio_src(&cinfo, infile);

    jpeg_read_header(&cinfo, TRUE);

    jpeg_start_decompress(&cinfo);

    int row_stride = cinfo.output_width * cinfo.output_components;
    /* Make a one-row-high sample array that will go away when done with image */

    int iBufMax = row_stride * cinfo.image_height;
    if (iBufMax <= buffMax.asInt())
    {
        
        long counter = 0;
        BYTE* pbyBuff = (BYTE*)rgbBuff.asPointer();

        JSAMPROW row_pointer[1];
        while (cinfo.output_scanline < cinfo.output_height) {
            row_pointer[0] = &pbyBuff[(cinfo.output_height - cinfo.output_scanline - 1) * row_stride];
            jpeg_read_scanlines(&cinfo, row_pointer, 1);

            //如果需要回显
            if (toUi && toUi[0])
            {
                OssJson request;
                OssJson& msg = request["msg"];

                request["to"] = toUi;
                msg["width"] = (int)cinfo.image_width;
                msg["height"] = (int)cinfo.image_height;
                msg["format"] = "RGB8";
                msg["data"] = pbyBuff;
                UpdateUi(request);
            }
        }

        response["result"] = "success";
    }
    else
    {
        response["result"] = "buffer not enough";
    }
    

    jpeg_finish_decompress(&cinfo);

    jpeg_destroy_decompress(&cinfo);

    fclose(infile);

    return MSG_OK;
}

